package com.smart.community.commons.utils;

import java.security.SecureRandom;
import java.util.Collection;
import java.util.regex.Pattern;

/**
 * 字符串工具类
 * @author Wu.Liang
 * @since 2024-12-19
 * @version 1.0.0
 */
public class StringUtils {
    
    /**
     * 空字符串
     */
    public static final String EMPTY = "";
    
    /**
     * 空格字符串
     */
    public static final String SPACE = " ";
    
    /**
     * 下划线
     */
    public static final String UNDERSCORE = "_";
    
    /**
     * 连字符
     */
    public static final String HYPHEN = "-";
    
    /**
     * 点号
     */
    public static final String DOT = ".";
    
    /**
     * 逗号
     */
    public static final String COMMA = ",";
    
    /**
     * 分号
     */
    public static final String SEMICOLON = ";";
    
    /**
     * 冒号
     */
    public static final String COLON = ":";
    
    /**
     * 等号
     */
    public static final String EQUALS = "=";
    
    /**
     * 问号
     */
    public static final String QUESTION_MARK = "?";
    
    /**
     * 和号
     */
    public static final String AMPERSAND = "&";
    
    /**
     * 斜杠
     */
    public static final String SLASH = "/";
    
    /**
     * 反斜杠
     */
    public static final String BACKSLASH = "\\";
    
    /**
     * 换行符
     */
    public static final String NEWLINE = "\n";
    
    /**
     * 回车符
     */
    public static final String CARRIAGE_RETURN = "\r";
    
    /**
     * 制表符
     */
    public static final String TAB = "\t";
    
    /**
     * 检查字符串是否为空
     * 
     * @param str 字符串
     * @return 是否为空
     */
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }
    
    /**
     * 检查字符串是否不为空
     * 
     * @param str 字符串
     * @return 是否不为空
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }
    
    /**
     * 检查字符串是否为空白
     * 
     * @param str 字符串
     * @return 是否为空白
     */
    public static boolean isBlank(String str) {
        if (isEmpty(str)) {
            return true;
        }
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 检查字符串是否不为空白
     * 
     * @param str 字符串
     * @return 是否不为空白
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }
    
    /**
     * 去除字符串两端空白
     * 
     * @param str 字符串
     * @return 去除空白后的字符串
     */
    public static String trim(String str) {
        return str == null ? null : str.trim();
    }
    
    /**
     * 去除字符串两端空白，如果为空则返回null
     * 
     * @param str 字符串
     * @return 去除空白后的字符串
     */
    public static String trimToNull(String str) {
        String trimmed = trim(str);
        return isEmpty(trimmed) ? null : trimmed;
    }
    
    /**
     * 去除字符串两端空白，如果为空则返回空字符串
     * 
     * @param str 字符串
     * @return 去除空白后的字符串
     */
    public static String trimToEmpty(String str) {
        return str == null ? EMPTY : str.trim();
    }
    
    /**
     * 字符串连接
     * 
     * @param elements 元素数组
     * @return 连接后的字符串
     */
    public static String join(Object... elements) {
        return join(elements, EMPTY);
    }
    
    /**
     * 字符串连接
     * 
     * @param elements 元素数组
     * @param separator 分隔符
     * @return 连接后的字符串
     */
    public static String join(Object[] elements, String separator) {
        if (elements == null) {
            return null;
        }
        if (separator == null) {
            separator = EMPTY;
        }
        
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < elements.length; i++) {
            if (i > 0) {
                sb.append(separator);
            }
            sb.append(elements[i]);
        }
        return sb.toString();
    }
    
    /**
     * 字符串连接
     * 
     * @param collection 集合
     * @param separator 分隔符
     * @return 连接后的字符串
     */
    public static String join(Collection<?> collection, String separator) {
        if (collection == null) {
            return null;
        }
        return join(collection.toArray(), separator);
    }
    
    /**
     * 字符串分割
     * 
     * @param str 字符串
     * @param separator 分隔符
     * @return 分割后的字符串数组
     */
    public static String[] split(String str, String separator) {
        if (isEmpty(str)) {
            return new String[0];
        }
        if (separator == null) {
            return new String[]{str};
        }
        return str.split(Pattern.quote(separator));
    }
    
    /**
     * 字符串分割
     * 
     * @param str 字符串
     * @param separator 分隔符
     * @param limit 限制分割数量
     * @return 分割后的字符串数组
     */
    public static String[] split(String str, String separator, int limit) {
        if (isEmpty(str)) {
            return new String[0];
        }
        if (separator == null) {
            return new String[]{str};
        }
        return str.split(Pattern.quote(separator), limit);
    }
    
    /**
     * 字符串替换
     * 
     * @param str 字符串
     * @param searchStr 搜索字符串
     * @param replacement 替换字符串
     * @return 替换后的字符串
     */
    public static String replace(String str, String searchStr, String replacement) {
        if (isEmpty(str) || isEmpty(searchStr) || replacement == null) {
            return str;
        }
        return str.replace(searchStr, replacement);
    }
    
    /**
     * 字符串替换（忽略大小写）
     * 
     * @param str 字符串
     * @param searchStr 搜索字符串
     * @param replacement 替换字符串
     * @return 替换后的字符串
     */
    public static String replaceIgnoreCase(String str, String searchStr, String replacement) {
        if (isEmpty(str) || isEmpty(searchStr) || replacement == null) {
            return str;
        }
        return str.replaceAll("(?i)" + Pattern.quote(searchStr), replacement);
    }
    
    /**
     * 字符串反转
     * 
     * @param str 字符串
     * @return 反转后的字符串
     */
    public static String reverse(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return new StringBuilder(str).reverse().toString();
    }
    
    /**
     * 首字母大写
     * 
     * @param str 字符串
     * @return 首字母大写的字符串
     */
    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
    
    /**
     * 首字母小写
     * 
     * @param str 字符串
     * @return 首字母小写的字符串
     */
    public static String uncapitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toLowerCase() + str.substring(1);
    }
    
    /**
     * 驼峰命名转下划线命名
     * 
     * @param str 驼峰命名字符串
     * @return 下划线命名字符串
     */
    public static String camelToUnderscore(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
    }
    
    /**
     * 下划线命名转驼峰命名
     * 
     * @param str 下划线命名字符串
     * @return 驼峰命名字符串
     */
    public static String underscoreToCamel(String str) {
        if (isEmpty(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        boolean nextUpper = false;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == '_') {
                nextUpper = true;
            } else {
                if (nextUpper) {
                    sb.append(Character.toUpperCase(c));
                    nextUpper = false;
                } else {
                    sb.append(Character.toLowerCase(c));
                }
            }
        }
        return sb.toString();
    }
    
    /**
     * 检查字符串是否包含指定字符
     * 
     * @param str 字符串
     * @param searchStr 搜索字符串
     * @return 是否包含
     */
    public static boolean contains(String str, String searchStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        return str.contains(searchStr);
    }
    
    /**
     * 检查字符串是否包含指定字符（忽略大小写）
     * 
     * @param str 字符串
     * @param searchStr 搜索字符串
     * @return 是否包含
     */
    public static boolean containsIgnoreCase(String str, String searchStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        return str.toLowerCase().contains(searchStr.toLowerCase());
    }
    
    /**
     * 检查字符串是否以指定前缀开始
     * 
     * @param str 字符串
     * @param prefix 前缀
     * @return 是否以指定前缀开始
     */
    public static boolean startsWith(String str, String prefix) {
        if (str == null || prefix == null) {
            return false;
        }
        return str.startsWith(prefix);
    }
    
    /**
     * 检查字符串是否以指定后缀结束
     * 
     * @param str 字符串
     * @param suffix 后缀
     * @return 是否以指定后缀结束
     */
    public static boolean endsWith(String str, String suffix) {
        if (str == null || suffix == null) {
            return false;
        }
        return str.endsWith(suffix);
    }
    
    /**
     * 获取字符串长度
     * 
     * @param str 字符串
     * @return 长度
     */
    public static int length(String str) {
        return str == null ? 0 : str.length();
    }
    
    /**
     * 左填充
     * 
     * @param str 字符串
     * @param size 目标长度
     * @param padChar 填充字符
     * @return 填充后的字符串
     */
    public static String leftPad(String str, int size, char padChar) {
        if (str == null) {
            return null;
        }
        int pads = size - str.length();
        if (pads <= 0) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < pads; i++) {
            sb.append(padChar);
        }
        sb.append(str);
        return sb.toString();
    }
    
    /**
     * 右填充
     * 
     * @param str 字符串
     * @param size 目标长度
     * @param padChar 填充字符
     * @return 填充后的字符串
     */
    public static String rightPad(String str, int size, char padChar) {
        if (str == null) {
            return null;
        }
        int pads = size - str.length();
        if (pads <= 0) {
            return str;
        }
        StringBuilder sb = new StringBuilder(str);
        for (int i = 0; i < pads; i++) {
            sb.append(padChar);
        }
        return sb.toString();
    }
    
    /**
     * 生成32位随机字符串
     * 
     * 用于生成店铺编码等唯一标识符
     * 使用数字和字母组合，确保唯一性和可读性
     * 
     * @return 32位随机字符串
     */
    public static String generateRandomString32() {
        return generateRandomString(32);
    }
    
    /**
     * 生成指定长度的随机字符串
     * 
     * 使用数字和字母组合，确保唯一性和可读性
     * 
     * @param length 字符串长度
     * @return 指定长度的随机字符串
     */
    public static String generateRandomString(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("字符串长度必须大于0");
        }
        
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);
        
        for (int i = 0; i < length; i++) {
            int index = random.nextInt(chars.length());
            sb.append(chars.charAt(index));
        }
        
        return sb.toString();
    }
}
